package gti310.tp4;

import java.util.ArrayList;

/**
 * The Main class is where the different functions are called to either encode
 * a PPM file to the Squeeze-Light format or to decode a Squeeze-Ligth image
 * into PPM format. It is the implementation of the simplified JPEG block 
 * diagrams.
 * 
 * @author Fran?ois Caron
 */
public class Main {

	/*
	 * The entire application assumes that the blocks are 8x8 squares.
	 */
	public static final int BLOCK_SIZE = 8;
	
	/*
	 * The number of dimensions in the color spaces.
	 */
	public static final int COLOR_SPACE_SIZE = 3;
	
	/*
	 * The number of dimensions in the facteur qualit?.
	 */
	public static int FACT_QUALITE = 0;
	
	/*
	/*
	 * The RGB color space.
	 */
	public static final int R = 0;
	public static final int G = 1;
	public static final int B = 2;
	
	/*
	 * The YUV color space.
	 */
	public static final int Y = 0;
	public static final int U = 1;
	public static final int V = 2;
	
	/**
	 * The application's entry point.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		
		System.out.println("Squeeze Light Media Codec !");
		FACT_QUALITE = Integer.parseInt(args[0]);
		
		//Lecture du fichier, création et conversion des matrices de couleur
		ImageConverter conv = new ImageConverter(PPMReaderWriter.readPPMFile(args[1]));
		
		//Découpage 8x8
		ImageBlockMaker block = new ImageBlockMaker(conv.RGBtoYCbCr());
		block.diviserBlock();
		
		//Sauvegarde de la liste dans une classe
		ListeComposant liste = new ListeComposant(block.getComponentList());
		
		//Application de la DCT
		dct conversion = new dct(liste);
		conversion.executerDCT();		
		
		//Application de la dpcm
		dpcm d = new dpcm(liste);
		ArrayList<double[]> listeCoeffDC = d.process();
		
		//Application de la quantification
		quantification q = new quantification(FACT_QUALITE, liste);
		q.executerQuantification();
		
		//Application du Zig-Zag
		zigzag ZZ = new zigzag(liste);
		ZZ.executerZigZag();
		
		//Application de la RLC
		rlc r = new rlc(liste);
		ArrayList<ArrayList<rlcLocator>> listeCoeffAC = r.process();
		
		//Enregistrement dans le fichier szl
		Entropy en = new Entropy();
		SZLReaderWriter szlrw = new SZLReaderWriter();
		
		//Ecriture des coeff DC dans le bit buffer
		for (int i = 0; i < listeCoeffDC.size(); i++) {
			for(int j=0;j<listeCoeffDC.get(i).length;j++){
				en.writeDC((int)listeCoeffDC.get(i)[j]);
			}
		}
		
		//Ecriture des coeff AC dans le bit buffer
		for (int i = 0; i < listeCoeffAC.size(); i++) {
			for(int j=0;j<listeCoeffAC.get(i).size();j++){
				int runlength = listeCoeffAC.get(i).get(j).getRunLength();
				int value = listeCoeffAC.get(i).get(j).getValue();
				en.writeAC(runlength, value);
			}
		}	
		
		//Ecriture du fichier
		szlrw.writeSZLFile(args[2], 256, 256, FACT_QUALITE);				
	}	
}